#pragma once
#include <string>
#include <sstream>
#include <map>
#include <functional>

#include "../Headers/types.h"

namespace TOB {

  // forward
  class Shell;

  /// Command handler
  using commandHandler = std::function<void(Shell&, std::stringstream&)>;

  /// Command interpreter
  class Shell {
   private:
    bool running;

   protected:
    std::string title;

   public:
    /**
     * Constructor
     *
     * @param title Current shell title
     */
    Shell(std::string title="shell");

    /**
     * Destructor
     */
    virtual ~Shell();

    /**
     * Start listening
     */
    void start();

    /**
     * End listening
     */
    void stop();

    /**
     * Ask for text
     *
     * @param text Output string
     * @param msg Text to be shown before input
     */
    Shell &getText(std::string &text, std::string msg="User input");

    /**
     * Ask for password
     *
     * @param password Output string
     */
    Shell &getPassword(std::string &password);

    /**
     * Write string
     *
     * @param msg Output message
     */
    Shell &write(std::string msg);

    /**
     * Write integer
     *
     * @param msg Output message
     */
    Shell &write(int32 msg);

    /**
     * Write unsigned integer
     *
     * @param msg Output message
     */
    Shell &write(uint32 msg);

    /**
     * Write line 
     */
    Shell &writeLine();

    /**
     * Write error
     *
     * @param msg Error message
     */
    Shell &error(std::string msg);

    /**
     * Wrong parameter error
     *
     * @param param What param is wrong
     */
    void wrongParam(std::string param);

    /**
     * Handlers map
     */
    std::map<std::string, commandHandler> at;
  };
}
